package gatperdut.chato.lucene.parser;

import gatperdut.chato.constants.CSConstantsLucene;
import gatperdut.chato.lucene.parseresult.CMParseResult;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;

public abstract class CMParser {

    private final CMParseResult parseResult;

    private final XMLEventReader eventReader;

    private final String IS_COALESCING = "javax.xml.stream.isCoalescing";

    public CMParser( File fileToParse, CMParseResult parseResult ) throws FileNotFoundException, XMLStreamException {
        this.parseResult = parseResult;

        XMLInputFactory inputFactory = XMLInputFactory.newInstance();
        // --if not set to true, treats double carriage returns as separate events when reading tags (resulting in split blocks of text).
        inputFactory.setProperty( IS_COALESCING, true );
        InputStream in = new FileInputStream( fileToParse );
        eventReader = inputFactory.createXMLEventReader( in );
    }

    public abstract void dealWithEvent( XMLEvent event ) throws XMLStreamException;

    public void parse() throws XMLStreamException {
        while ( getEventReader().hasNext() ) {
            XMLEvent event = getEventReader().nextEvent();
            if ( event.isStartElement() ) {
                if ( event.asStartElement().getName().getLocalPart().equals( CSConstantsLucene.FIELD_TOPIC ) ) {
                    event = getEventReader().nextEvent();
                    String topic = event.asCharacters().getData();
                    getParseResult().setTopic( topic );
                }
                else if ( event.asStartElement().getName().getLocalPart().equals( CSConstantsLucene.FIELD_TITLE ) ) {
                    event = getEventReader().nextEvent();
                    String title = event.asCharacters().getData();
                    getParseResult().setTitle( title );
                    getParseResult().getCatchAll().append( title + " " );
                }
                else if ( event.asStartElement().getName().getLocalPart().equals( CSConstantsLucene.FIELD_RELATED ) ) {
                    event = getEventReader().nextEvent();
                    String related = event.asCharacters().getData();
                    getParseResult().getSeeAlso().add( related );
                }
                else {
                    dealWithEvent( event );
                }
            }
        }
    }

    public CMParseResult getParseResult() {
        return parseResult;
    }

    public XMLEventReader getEventReader() {
        return eventReader;
    }

}
